package exception;

import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import response.ResponseCode;
import response.ResponseData;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.nio.charset.Charset;

/**
 * wdap-manager服务全局异常处理
 * 抛出异常时记录请求参数，服务名，traceId，异常原因，请求IP，sessionId，userId等等信息
 */
@ControllerAdvice
public class BusiExceptionHandler {
    private final static Logger logger = LoggerFactory.getLogger(BusiExceptionHandler.class);

    //@Autowired(required = false)
    //protected Tracer tracer;

    @Value("${spring.application.name}")
    public String SERVICE_NAME;

/*
    @Override
    public String getServiceName() {
        return this.SERVICE_NAME;
    }
    abstract public String getServiceName();*/
    /**
     * 处理业务异常
     *
     * @param e       业务异常
     * @param request 请求内容
     * @return 异常信息
     */
    @ResponseBody
    @ExceptionHandler(BusiException.class)
    public ResponseData handlerBusiException(BusiException e, HttpServletRequest request) {
        logger.error("", e);
        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        String params = JSONObject.toJSONString(request.getParameterMap());
        //返回错误信息(不包含详细信息)
        ResponseData responseData = ResponseData.error(ResponseCode.BUSINESS_EXCEPTION.getCode(), ResponseCode.BUSINESS_EXCEPTION.getDesc() + ":" + e.getMessage());
        //请求方法
        String method = request.getMethod();
        //服务名称
        String serviceName = this.SERVICE_NAME;
        //traceId
        //String traceId = tracer.currentSpan().context().traceIdString();

        //logger.error("SERVICE:{};ERROR:{};TRACER-ID:{};METHOD:{};PARAMS:{}",serviceName,e.getMessage(),traceId,method,params);
        logger.error("SERVICE:{};ERROR:{};METHOD:{};PARAMS:{}", serviceName, e.getMessage(), method, params);
        //TODO 记录到数据库
        return responseData;
    }

    /**
     * 处理未知异常
     *
     * @param e       异常
     * @param request 请求
     * @return
     */
    @ResponseBody
    @ExceptionHandler(Exception.class)
    public ResponseData handlerException(Exception e, HttpServletRequest request) throws IOException {
        logger.error("", e);
        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

        //请求方法
        String method = request.getMethod();
        //请求参数
        String params = null;
        if ("GET".equalsIgnoreCase(method)) {
            params = JSONObject.toJSONString(request.getParameterMap());
        } else if ("POST".equalsIgnoreCase(method)) {
            String contentType = request.getContentType();
            if ("application/json".equalsIgnoreCase(contentType)) {
                params = StreamUtils.copyToString(request.getInputStream(), Charset.forName("UTF-8"));
            }
        }
        //服务名称
        String serviceName = this.SERVICE_NAME;
        //traceId
        //String traceId = tracer.currentSpan().context().traceIdString();

        //logger.error("SERVICE:{};ERROR:{};TRACER-ID:{};METHOD:{};PARAMS:{}",serviceName,e.getMessage(),traceId,method,params);
        logger.error("SERVICE:{};ERROR:{};METHOD:{};PARAMS:{}", serviceName, e.getMessage(), method, params);
        //TODO 记录到数据库

        //返回错误信息(不包含详细信息)
        return ResponseData.error(ResponseCode.SERVER_ERROR.getCode(), ResponseCode.SERVER_ERROR.getDesc() + ":" + e.getMessage());
    }
}
